<template>
  <el-dialog
    title="素材库"
    v-model="visible"
    top="10vh"
    width="88%"
    :before-close="handleClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <div class="file-wrap" v-loading="loading">
      <div class="ossItems">
        <div v-for="item in dataList" :class="{ ossItem: true, checked: item.checked}" :key="item.id" @click="selectOssEvent(item)">
          <el-image
            fit="contain"
            style="max-width: 100%; height: auto"
            :src="item.urlAll"
            v-if="item.fileType === 'image'"
          >
            <template #error>
              <div class="image-error">
                <el-icon><icon-picture /></el-icon>
              </div>
            </template>
          </el-image>
          <svg-icon :name="`file-${item.fileType}`" v-else></svg-icon>
        </div>
      </div>
      <el-pagination background @current-change="refreshData" :page-size="20" layout="prev, pager, next" :total="total" v-if="total > 0" />
    </div>
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="getCheckedOss">确定</el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, watch, type PropType, computed } from 'vue'
import { Picture as IconPicture } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { UPDATE_MODEL_EVENT } from 'cm/contants'

import { getFileList, type OssApiResult } from '@/api/oss'
import type { ListResultData } from '@/api/base'
import { useApiLock } from '_hooks'
import appConfig from '@/config/index'

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true,
    default: false
  }
})

/**
 * 根据 mime type 判断文件类型，并返回统一数据
 * 图片 则返回 image
 * pptx ppt 返回 ppt
 * xls xlsx 返回 excel
 */
const fileType = (mimeType: any) => {
  if (/image\/.*$/.test(mimeType)) {
    return 'image'
  } else if (
    ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'].includes(mimeType)
  ) {
    return 'doc'
  } else if (
    [
      'application/vnd.ms-powerpoint',
      'application/vnd.openxmlformats-officedocument.presentationml.presentation'
    ].includes(mimeType)
  ) {
    return 'ppt'
  } else if (
    ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'].includes(mimeType)
  ) {
    return 'excel'
  } else if (mimeType === 'text/plain') {
    return 'txt'
  } else if (mimeType === 'application/pdf') {
    return 'pdf'
  }
  return 'other'
}
const visible = ref<boolean>(false)
const loading = ref<boolean>(false)
const total = ref<number>(0)
const dataList = ref<Array<OssApiResult>>([])
const getFileListApi = async ({ page = 1, size = 20 }) => {
  loading.value = true
  const res = await useApiLock(async () => await getFileList({page, size,}),500)
  loading.value = false
  if (res?.code === 200) {
    let data = res.data as ListResultData<OssApiResult>;
    data.list.forEach(item => {
      item.urlAll = `${appConfig.api.staticUrl}${item.url}`
      item.fileType = fileType(item.type)
      item.checked = false
    })
    dataList.value = data.list
    total.value = data.total
  } else {
    ElMessage.error(res?.msg || '网络异常，请稍后重试')
  }
}

const refreshData = (e: number) => {
  getFileListApi({ page: e, size: 20 })
}

watch(
  () => props.modelValue,
  async () => {
    visible.value = props.modelValue
    if (props.modelValue) {
      await getFileListApi({ page: 1, size: 20 })
    }
  }
)

const checkList = ref<Array<any>>([])
const selectOssEvent = (row: OssApiResult) => {
  row.checked = row.checked ? false : true
}

const getCheckedOss = () => {
  checkList.value = dataList.value.filter(item => item.checked);
  const imgArrays: Array<object> = checkList.value.map((item, index) => {
    const obj = {
        uid: parseInt(item.id),
        url: `${appConfig.api.staticUrl}${item.url}`,
        name: item.url
      }
      return obj
  })
  checkList.value = imgArrays;
  emit('change', checkList.value)
  handleClose();
}

const emit = defineEmits([UPDATE_MODEL_EVENT, 'change'])
const handleClose = () => {
  emit(UPDATE_MODEL_EVENT, false)
}
</script>

<style lang="scss" scoped>
.ossItems {
  display: flex;
  flex-wrap: wrap;
}
.ossItem {
  width: calc((100% - 120px) / 5);
  margin-right: 30px;
  margin-bottom: 30px;
  cursor: pointer;

  .el-image {
    background-color: #000;

    :deep(img) {
      opacity: 0.5;
    }
  }
}

.ossItem.checked {
  .el-image {
    :deep(img) {
      opacity: 1;
    }
  }
}

.ossItem:nth-of-type(5n) {
  margin-right: 0;
}

.file-wrap {
  font-size: 50px;

  .image-error {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: var(--el-fill-color-light);
    color: var(--el-text-color-secondary);
  }
}
</style>
